home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / perl5 / Mail / Mailer.pm < prev    next >
Text File  |  2008-07-29  |  5KB  |  209 lines

  1. # Copyrights 1995-2008 by Mark Overmeer <perl@overmeer.net>.
  2. #  For other contributors see ChangeLog.
  3. # See the manual pages for details on the licensing terms.
  4. # Pod stripped from pm file by OODoc 1.05.
  5. use strict;
  6.  
  7. package Mail::Mailer;
  8. use vars '$VERSION';
  9. $VERSION = '2.04';
  10.  
  11. use base 'IO::Handle';
  12.  
  13. use POSIX qw/_exit/;
  14.  
  15. use Carp;
  16. use Config;
  17.  
  18.  
  19.  
  20. sub is_exe($);
  21.  
  22. sub Version { our $VERSION }
  23.  
  24. our @Mailers =
  25.   ( sendmail => '/usr/lib/sendmail;/usr/sbin/sendmail;/usr/ucblib/sendmail'
  26.   , smtp     => undef
  27.   , qmail    => '/usr/sbin/qmail-inject;/var/qmail/bin/qmail-inject'
  28.   , testfile => undef
  29.   );
  30.  
  31. push @Mailers, map { split /\:/, $_, 2 }
  32.                    split /$Config{path_sep}/, $ENV{PERL_MAILERS}
  33.     if $ENV{PERL_MAILERS};
  34.  
  35. our %Mailers = @Mailers;
  36. our $MailerType;
  37. our $MailerBinary;
  38.  
  39. # does this really need to be done? or should a default mailer be specfied?
  40.  
  41. $Mailers{sendmail} = 'sendmail'
  42.     if $^O eq 'os2' && ! is_exe $Mailers{sendmail};
  43.  
  44. if($^O =~ m/^ (?: MacOS|VMS|MSWin|os2|NetWare ) $/x )
  45. {   $MailerType   = 'smtp';
  46.     $MailerBinary = $Mailers{$MailerType};
  47. }
  48. else
  49. {   for(my $i = 0 ; $i < @Mailers ; $i += 2)
  50.     {   $MailerType = $Mailers[$i];
  51.         if(my $binary = is_exe $Mailers{$MailerType})
  52.         {   $MailerBinary = $binary;
  53.             last;
  54.         }
  55.     }
  56. }
  57.  
  58. sub import
  59. {   shift;  # class
  60.     @_ or return;
  61.  
  62.     my $type = shift;
  63.     my $exe  = shift || $Mailers{$type};
  64.  
  65.     is_exe $exe
  66.         or carp "Cannot locate '$exe'";
  67.  
  68.     $MailerType = $type;
  69.     $Mailers{$MailerType} = $exe;
  70. }
  71.  
  72. sub to_array($)
  73. {   my ($self, $thing) = @_;
  74.     ref $thing ? @$thing : $thing;
  75. }
  76.  
  77. sub is_exe($)
  78. {   my $exe = shift || '';
  79.  
  80.     foreach my $cmd (split /\;/, $exe)
  81.     {   $cmd =~ s/^\s+//;
  82.  
  83.         # remove any options
  84.         my $name = ($cmd =~ /^(\S+)/)[0];
  85.  
  86.         # check for absolute or relative path
  87.         return $cmd
  88.             if -x $name && ! -d $name && $name =~ m![\\/]!;
  89.  
  90.         if(defined $ENV{PATH})
  91.         {   foreach my $dir (split /$Config{path_sep}/, $ENV{PATH})
  92.             {   return "$dir/$cmd"
  93.                 if -x "$dir/$name" && ! -d "$dir/$name";
  94.             }
  95.         }
  96.     }
  97.     0;
  98. }
  99.  
  100.  
  101. sub new($@)
  102. {   my ($class, $type, @args) = @_;
  103.  
  104.     $type ||= $MailerType
  105.           ||  croak "No MailerType specified";
  106.  
  107.     my $exe = $Mailers{$type};
  108.  
  109.     if(defined $exe)
  110.     {   $exe   = is_exe $exe
  111.             if defined $type;
  112.  
  113.         $exe ||= $MailerBinary
  114.              ||  croak "No mailer type specified (and no default available), thus can not find executable program.";
  115.     }
  116.  
  117.     $class = "Mail::Mailer::$type";
  118.     eval "require $class" or die $@;
  119.  
  120.     my $glob = $class->SUPER::new;   # object is a GLOB!
  121.     %{*$glob} = (Exe => $exe, Args => [ @args ]);
  122.     $glob;
  123. }
  124.  
  125.  
  126. sub open($)
  127. {   my ($self, $hdrs) = @_;
  128.     my $exe    = *$self->{Exe};   # no exe, then direct smtp
  129.     my $args   = *$self->{Args};
  130.  
  131.     my @to     = $self->who_to($hdrs);
  132.     my $sender = $self->who_sender($hdrs);
  133.     
  134.     $self->close;    # just in case;
  135.  
  136.     if(defined $exe)
  137.     {   # Fork and start a mailer
  138.         my $child = open $self, '|-';
  139.         defined $child or die "Failed to send: $!";
  140.  
  141.         if($child==0)
  142.         {   # Child process will handle sending, but this is not real exec()
  143.             # this is a setup!!!
  144.             unless($self->exec($exe, $args, \@to, $sender))
  145.             {   warn $!;     # setup failed
  146.                 _exit(1);    # no DESTROY(), keep it for parent
  147.             }
  148.         }
  149.     }
  150.     else
  151.     {   $self->exec($exe, $args, \@to, $sender)
  152.             or die $!;
  153.     }
  154.  
  155.     $self->set_headers($hdrs);
  156.     $self;
  157. }
  158.  
  159. sub _cleanup_hdrs($)
  160. {   foreach my $h (values %{(shift)})
  161.     {   foreach (ref $h ? @$h : $h)
  162.         {   s/\n\s*/ /g;
  163.             s/\s+$//;
  164.         }
  165.     }
  166. }
  167.  
  168. sub exec($$$$)
  169. {   my($self, $exe, $args, $to, $sender) = @_;
  170.  
  171.     # Fork and exec the mailer (no shell involved to avoid risks)
  172.     my @exe = split /\s+/, $exe;
  173.     exec @exe, @$args, @$to;
  174. }
  175.  
  176. sub can_cc { 1 }    # overridden in subclass for mailer that can't
  177.  
  178. sub who_to($)
  179. {   my($self, $hdrs) = @_;
  180.     my @to = $self->to_array($hdrs->{To});
  181.     unless($self->can_cc)  # Can't cc/bcc so add them to @to
  182.     {   push @to, $self->to_array($hdrs->{Cc} ) if $hdrs->{Cc};
  183.         push @to, $self->to_array($hdrs->{Bcc}) if $hdrs->{Bcc};
  184.     }
  185.     @to;
  186. }
  187.  
  188. sub who_sender($)
  189. {   my ($self, $hdrs) = @_;
  190.     ($self->to_array($hdrs->{Sender} || $hdrs->{From}))[0];
  191. }
  192.  
  193. sub epilogue {
  194.     # This could send a .signature, also see ::smtp subclass
  195. }
  196.  
  197. sub close(@)
  198. {   my $self = shift;
  199.     fileno $self or return;
  200.  
  201.     $self->epilogue;
  202.     CORE::close $self;
  203. }
  204.  
  205. sub DESTROY { shift->close }
  206.  
  207.  
  208. 1;
  209.